home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / blankery / agblankers / source / trek / blank.c next >
C/C++ Source or Header  |  1995-02-27  |  14KB  |  488 lines

  1. /* --------------------------------------------------------
  2.  *    Draw important lamps like in star trek
  3.  *                                           010294 kha.
  4.  * -------------------------------------------------------- */
  5.  
  6. #include <exec/memory.h>
  7. #include <math.h>
  8. #include <stdlib.h>
  9.  
  10. #ifdef DEBUG
  11. #include <stdio.h>
  12. #endif
  13.  
  14. #include "/includes.h"
  15.  
  16. #define bool int
  17. #ifndef TRUE
  18. #define TRUE 1
  19. #define FALSE 0
  20. #endif
  21.  
  22. #define MAXLENGTH 10
  23. #define MAXLAMP   8000
  24. #define WHITE_PEN 1
  25. #define BLACK_PEN 2
  26.  
  27.  
  28. Triplet *ColorTable = 0L;
  29.  
  30. /* One entry of a pulsing rhythm */
  31. typedef struct
  32. { int color;                /* To which color should we switch */
  33.   int delay;                /* How long should we keep this color */
  34. } rhentry;
  35.  
  36. /* a complete rhytm sequence */
  37. typedef struct 
  38. { int length;               /* How many items of data are filled */
  39.   rhentry data[MAXLENGTH];  /* Array of the items */
  40. } rhythm;
  41.   
  42. /* The properties of any lamp */
  43. typedef struct
  44. { int    x,y,width,height;  /* The size on the screen */
  45.   rhythm *rh;               /* A pointer to the rhythm we want */
  46.   int    stage;             /* which data element of our rhythm is current */
  47.   int    count;             /* How many delay steps have passed since the
  48.                              * activation of this data element */
  49. } lamp;
  50.  
  51.  
  52. #ifdef DEBUG
  53. int theheight;
  54. int thewidth;
  55. #endif
  56.  
  57.  
  58. #define RHYTHMS 0
  59. #define DURATION 2
  60. #define DELAY 4
  61. #define WIDTH 6
  62. #define HEIGHT 8
  63. #define SUBMODE 10
  64. #define GREYBG 11
  65. #define FREEMODE 13
  66. #define MODE 15
  67.  
  68.  
  69. void breakme(void)
  70. { while(1){}
  71. }
  72.  
  73. VOID Defaults( PrefObject *Prefs )
  74. {
  75.         Prefs[RHYTHMS].po_Level = 20;
  76.         Prefs[DURATION].po_Level = 500;
  77.         Prefs[DELAY].po_Level = 1;
  78.         Prefs[WIDTH].po_Level = 50;
  79.         Prefs[HEIGHT].po_Level = 50;
  80.         Prefs[SUBMODE].po_Level = 1;
  81.         Prefs[GREYBG].po_Level = 1;
  82.         Prefs[FREEMODE].po_Level = 50;
  83.     Prefs[MODE].po_ModeID = getTopScreenMode();
  84.     Prefs[MODE].po_Depth = 4;
  85. }
  86.  
  87. int MINWIDTH;
  88. int MINHEIGHT;
  89. int submode;
  90. int freemode;
  91.  
  92. /* Generate a set of num rhythm sequences for lamps with up to colors colors */
  93. void generate_rhythms(rhythm *r, int num, int colors)
  94. { int i;
  95.   rhythm *curr_r = r;
  96.   rhentry *curr_e;
  97.  
  98.   for (i=0; i<num; i++)
  99.     { curr_e = curr_r->data;
  100.       switch(RangeRand(4))
  101.     { case 0:
  102.         /* Ungleichmaessig schnelles blinken */
  103.         { int d1 = RangeRand(10)+10;
  104.           int d2 = RangeRand(10)+10;
  105.           int color = RangeRand(colors-3)+3;
  106.           curr_r->length = 2;
  107.           curr_e->color = color;
  108.           curr_e->delay = d1;
  109.           curr_e++;
  110.           curr_e->color = 0;
  111.           curr_e->delay = d2;
  112.           break;
  113.         }
  114.       case 1:
  115.         /* Gleichmaessiges blinken */
  116.         { int d1 = RangeRand(10)+10;
  117.           int color = RangeRand(colors-3)+3;
  118.           curr_r->length = 2;
  119.           curr_e->color = color;
  120.           curr_e->delay = d1;
  121.           curr_e++;
  122.           curr_e->color = 0;
  123.           curr_e->delay = d1;
  124.           break;
  125.         } 
  126.       case 2:
  127.         /* Farbwechsel (regelmaessig) */
  128.         { int d1 = RangeRand(10)+10;
  129.           int i;
  130.           curr_r->length = MAXLENGTH;
  131.           for (i=0; i<MAXLENGTH; i++)
  132.         { curr_e->color = (i % 2 ? RangeRand(colors-3)+3 : 0);
  133.           curr_e->delay = d1;
  134.           curr_e++;
  135.         }
  136.           break;
  137.         } 
  138.       } /* switch */
  139.       curr_r++;
  140.     } /* for */
  141. }
  142.  
  143.  
  144. int generate_lamp_row(lamp *l, struct RastPort *rp, int limit, bool vertical,
  145.               int x, int y, int width, int height, int rhythms, rhythm *r)
  146. { if (limit <= 0)
  147.     { return 0;
  148.     }
  149.   else if (width < MINWIDTH || height < MINHEIGHT)
  150.     { if (RangeRand(100)<freemode)
  151.         { return 0;
  152.         }
  153.       else if (submode && (width/height > 1 || height/width > 1))
  154.         { if (width/height > 1)
  155.             { int factor;
  156.               int remainder;
  157.               int cx,cy,i;
  158.               cx = x; cy = y;
  159.  
  160.               factor = width/height;
  161.               if (factor > limit)
  162.                 { factor = limit;
  163.                 }
  164.               remainder = width - factor * height;
  165.  
  166.               for (i=0; i<factor; i++)
  167.                 { int x1,y1,x2,y2;
  168.                   x1 = x + i*height + (remainder*i)/factor;
  169.                   y1 = y;
  170.                   x2 = x1 + height-1;
  171.                   y2 = y1 + height-1;
  172.                   l->x = x1+1; l->y = y1+1;
  173.                   l->width = height-2; l->height = height-2;
  174.                   l->stage = 0;
  175.                   l->count = 0;
  176.                   l->rh = r+RangeRand(rhythms);
  177.                   l++;
  178. #ifdef DEBUG
  179.                   if (x<0 || y<0 || x>thewidth || y>theheight)
  180.                       { printf("error! x,y = %d,%d\n",x,y);
  181.                       breakme();
  182.                     }
  183.                   if (x+width<0 || x+width>thewidth || y+height<0 || y+height>theheight)
  184.                     { printf("error! x+w,y+h = %d,%d\n",x+width,y+height);
  185.                       breakme();
  186.                       while(1) { printf(" "); }
  187.                     }
  188. #endif
  189.                   SetAPen(rp,WHITE_PEN);
  190.                   Move(rp,x1,y1);
  191.                   Draw(rp,x1,y2);
  192.                   Move(rp,x1,y1);
  193.                   Draw(rp,x2,y1);
  194.                   SetAPen(rp,BLACK_PEN);
  195.                   Move(rp,x1,y2);
  196.                   Draw(rp,x2,y2);
  197.                   Move(rp,x2,y1);
  198.                   Draw(rp,x2,y2);
  199.                 }
  200.               return factor;
  201.             }
  202.           else
  203.             { int factor;
  204.               int remainder;
  205.               int cx,cy,i;
  206.               cx = x; cy = y;
  207.  
  208.               factor = height/width;
  209.               if (factor > limit)
  210.                 { factor = limit;
  211.                 }
  212.               remainder = height - factor * width;
  213.  
  214.               for (i=0; i<factor; i++)
  215.                 { int x1,y1,x2,y2;
  216.                   y1 = y + i*width + (remainder*i)/factor;
  217.                   x1 = x;
  218.                   x2 = x1 + width-1;
  219.                   y2 = y1 + width-1;
  220.                   l->x = x1+1; l->y = y1+1;
  221.                   l->width = width-2; l->height = width-2;
  222.                   l->stage = 0;
  223.                   l->count = 0;
  224.                   l->rh = r+RangeRand(rhythms);
  225.           l++;
  226. #ifdef DEBUG
  227.                   if (x<0 || y<0 || x>thewidth || y>theheight)
  228.                       { printf("error! x,y = %d,%d\n",x,y);
  229.                       breakme();
  230.                     }
  231.                   if (x+width<0 || x+width>thewidth || y+height<0 || y+height>theheight)
  232.                     { printf("error! x+w,y+h = %d,%d\n",x+width,y+height);
  233.                       breakme();
  234.                       while(1) { printf(" "); }
  235.                     }
  236. #endif
  237.                   SetAPen(rp,WHITE_PEN);
  238.                   Move(rp,x1,y1);
  239.                   Draw(rp,x1,y2);
  240.                   Move(rp,x1,y1);
  241.                   Draw(rp,x2,y1);
  242.                   SetAPen(rp,BLACK_PEN);
  243.                   Move(rp,x1,y2);
  244.                   Draw(rp,x2,y2);
  245.                   Move(rp,x2,y1);
  246.                   Draw(rp,x2,y2);
  247.                 }
  248.               return factor;
  249.             }
  250.         }
  251.       else
  252.         { int x2,y2;
  253.           x2 = x+width-1;
  254.           y2 = y+height-1;
  255.           l->x = x+1; l->y = y+1;
  256.           l->width = width-2; l->height = height-2;
  257.           l->stage = 0;
  258.           l->count = 0;
  259.           l->rh = r+RangeRand(rhythms);
  260. #ifdef DEBUG
  261.           if (x<0 || y<0 || x>thewidth || y>theheight)
  262.            { printf("error! x,y = %d,%d\n",x,y);
  263.               breakme();
  264.             }
  265.           if (x+width<0 || x+width>thewidth || y+height<0 || y+height>theheight)
  266.             { printf("error! x+w,y+h = %d,%d\n",x+width,y+height);
  267.               breakme();
  268.               while(1) { printf(" "); }
  269.             }
  270. #endif
  271.           SetAPen(rp,WHITE_PEN);
  272.           Move(rp,x,y);
  273.           Draw(rp,x,y2);
  274.           Move(rp,x,y);
  275.           Draw(rp,x2,y);
  276.           SetAPen(rp,BLACK_PEN);
  277.           Move(rp,x,y2);
  278.           Draw(rp,x2,y2);
  279.           Move(rp,x2,y);
  280.           Draw(rp,x2,y2);
  281.           return 1;
  282.         }
  283.     }
  284.   else
  285.     { if (vertical)
  286.     { int xm = x + width/2 -1;
  287.       int x2 = x + width-1;
  288.       int y2 = y + height-1;
  289.       int num;
  290.  
  291.       if (RangeRand(2))
  292.         { /* ziehe eine Vertikale Linie */
  293.           int yd1 = y + height/7;
  294.           int yd2 = y + (height*6)/7-1;
  295. #ifdef DEBUG 
  296.               if (xm<0 || yd1<0 || xm>thewidth || yd1>theheight)
  297.             { printf("error! xm,yd1 = %d,%d\n",xm,yd1);
  298.           breakme();
  299.                   while(1) { printf(" "); }
  300.                 }
  301.               if (xm+1<0 || xm+1>thewidth || yd2<0 || yd2>theheight)
  302.                 { printf("error! xm+1,yd = %d,%d\n",xm+1,yd2);
  303.           breakme();
  304.                   while(1) { printf(" "); }
  305.                 }
  306. #endif
  307.           SetAPen(rp,BLACK_PEN);
  308.           Move(rp,xm,yd1);
  309.           Draw(rp,xm,yd2);
  310.           SetAPen(rp,WHITE_PEN);
  311.           Move(rp,xm+1,yd1);
  312.           Draw(rp,xm+1,yd2);
  313.         }
  314.       num = generate_lamp_row(l,rp,limit, RangeRand(2),
  315.                   x+1,y+1,width/2-4,height-2,rhythms,r);
  316.       num = num + generate_lamp_row(l+num,rp,limit-num,RangeRand(2),
  317.                     x+width/2+2,y+1,width/2-4,height-2,rhythms,r);
  318.       return num;
  319.     }
  320.       else
  321.     { int ym = y + height/2 -1;
  322.       int x2 = x + width-1;
  323.       int y2 = y + height-1;
  324.       int num;
  325.  
  326.       if (RangeRand(2))
  327.         { /* ziehe eine horizontale Linie */
  328.           int xd1 = x + width/7;
  329.           int xd2 = x + (width*6)/7-1;
  330. #ifdef DEBUG 
  331.               if (ym<0 || xd1<0 || ym>theheight || xd1>thewidth)
  332.             { printf("error! xd1,ym = %d,%d\n",xd1,ym);
  333.           breakme();
  334.                   while(1) { printf(" "); }
  335.                 }
  336.               if (xd2<0 || xd2>thewidth || ym+1<0 || ym+1>theheight)
  337.                 { printf("error! xd2,ym = %d,%d\n",xd2,ym+1);
  338.           breakme();
  339.                   while(1) { printf(" "); }
  340.                 }
  341. #endif
  342.           SetAPen(rp,BLACK_PEN);
  343.           Move(rp,xd1,ym);
  344.           Draw(rp,xd2,ym);
  345.           SetAPen(rp,WHITE_PEN);
  346.           Move(rp,xd1,ym+1);
  347.           Draw(rp,xd2,ym+1);
  348.         }
  349.       num = generate_lamp_row(l,rp,limit, RangeRand(2),
  350.                   x+1,y+1,width-2,height/2-4,rhythms,r);
  351.       num = num + generate_lamp_row(l+num,rp,limit-num,RangeRand(2),
  352.                     x+1,y+height/2+2,width-2,height/2-4,rhythms,r);
  353.       return num;
  354.     }
  355.     }
  356. }
  357.        
  358.  
  359.  
  360. LONG Trek( struct Screen *scr, SHORT width, SHORT height, PrefObject *Prefs)
  361. {
  362.   LONG flg_end        = OK;
  363.   int colors          = 1L << scr->BitMap.Depth;
  364.   int rhythms         = Prefs[RHYTHMS].po_Level;
  365.   int duration        = Prefs[DURATION].po_Level;
  366.   struct RastPort *rp = &( scr->RastPort );
  367.  
  368.   rhythm *slave, *curr_rhythm;
  369.   lamp   *show, *curr_lamp;
  370.   rhentry *curr_entry;
  371.  
  372.   int i,j,lamps,thedelay;
  373.  
  374.   MINWIDTH = Prefs[WIDTH].po_Level;
  375.   MINHEIGHT = Prefs[HEIGHT].po_Level;
  376.   submode = Prefs[SUBMODE].po_Level;
  377.   freemode = Prefs[FREEMODE].po_Level;
  378.   thedelay = Prefs[DELAY].po_Level;
  379.  
  380. #ifdef DEBUG
  381.   thewidth = width;
  382.   theheight = height;
  383. #endif
  384.  
  385.   /* Initialize data */
  386.   slave = malloc(rhythms * sizeof(rhythm));
  387.   show  = malloc(MAXLAMP * sizeof(lamp));
  388.  
  389.   while (flg_end == OK)
  390.     { generate_rhythms(slave,rhythms,colors);
  391.       SetRast( rp, 0 );
  392.       ScreenToFront( scr );
  393.       lamps = generate_lamp_row(show,rp,MAXLAMP,RangeRand(2),
  394.                 0,0,width,height,rhythms,slave);
  395.  
  396.       /* Display the current sequence */
  397.       for (i=0; i<duration && flg_end == OK; i++)
  398.     { curr_lamp = show;
  399.  
  400.           /* simulate one clock cycle of each lamp */
  401.       for (j=0; j<lamps; j++)
  402.         { curr_rhythm = curr_lamp->rh;
  403.           curr_entry  = curr_rhythm->data+(curr_lamp->stage);
  404.           (curr_lamp->count)++;
  405.           if (curr_lamp->count >= curr_entry->delay)
  406.         { /* Lamp reaches a new stage */
  407.           curr_lamp->stage++;
  408.           curr_lamp->count = 0;
  409.           curr_entry++;
  410.           if (curr_lamp->stage >= curr_rhythm->length)
  411.             { /* all stages done, start with first stage */
  412.               curr_lamp->stage = 0;
  413.               curr_entry = curr_rhythm->data;
  414.             }
  415.           /* paint our lamp */
  416.           SetAPen(rp,curr_entry->color);
  417. #ifdef DEBUG
  418.                   if (curr_lamp->x < 0 || curr_lamp->y < 0 ||
  419.                       curr_lamp->width > width || curr_lamp->height > height)
  420.                     { printf("error! x,y = %d,%d, w,h = %d, %d\n",curr_lamp->x, curr_lamp->y,
  421.                              curr_lamp->width, curr_lamp->height);
  422.           breakme();
  423.                       while(1) { printf(" "); }
  424.                     }
  425. #endif
  426.           RectFill(rp,curr_lamp->x,curr_lamp->y,
  427.                   curr_lamp->x+curr_lamp->width-1,
  428.                   curr_lamp->y+curr_lamp->height-1);
  429.         }
  430.               curr_lamp++;
  431.         } /* for j */
  432.       ScreenToFront(scr);
  433.       flg_end = ContinueBlanking();
  434.           for (j=0; j<thedelay && flg_end == OK; j++) 
  435.             { Delay(1);
  436.           ScreenToFront(scr);
  437.             flg_end = ContinueBlanking();
  438.             }
  439.     } /* for i */
  440.     } /* while */
  441.   free(slave);
  442.   free(show);
  443.   return flg_end;
  444. }
  445.  
  446.  
  447. /* Adopted from the Dragon blanker */
  448. LONG Blank( PrefObject *Prefs )
  449. {
  450.     struct Screen *Scr;
  451.     struct Window *Wnd;
  452.     LONG RetVal;
  453.  
  454.     if( Scr = OpenScreenTags( NULL, SA_Depth, Prefs[MODE].po_Depth,
  455.                              SA_Quiet, TRUE, SA_DisplayID, Prefs[MODE].po_ModeID,
  456.                              SA_Behind, TRUE, SA_Overscan, OSCAN_STANDARD,
  457.                              TAG_DONE ))
  458.     {
  459.         SetRGB4(&( Scr->ViewPort ), 0, 0, 0, 0 );
  460.         ColorTable = RainbowPalette( Scr, 0L, 1L, 0L );
  461.                 if (Prefs[MODE].po_Depth > 1)
  462.                   {
  463.                     if (Prefs[GREYBG].po_Level)
  464.                   { SetRGB4(&( Scr->ViewPort ), 2, 0, 0, 0 );
  465.                   SetRGB4(&( Scr->ViewPort ), 1, 15,15,15 );
  466.                 SetRGB4(&( Scr->ViewPort ), 0, 8,8,8);
  467.                       } 
  468.                     else
  469.                       { SetRGB4(&( Scr->ViewPort ), 1, 15,15,15 );
  470.                 SetRGB4(&( Scr->ViewPort ), 2, 8,8,8);
  471.                       }
  472.                   }
  473.         Wnd = BlankMousePointer( Scr );
  474.         
  475.         do
  476.           RetVal = Trek( Scr, Scr->Width, Scr->Height, Prefs );
  477.         while( RetVal == OK );
  478.         
  479.         UnblankMousePointer( Wnd );
  480.         RainbowPalette( 0L, ColorTable, 1L, 0L );
  481.         CloseScreen( Scr );
  482.     }
  483.     else
  484.         RetVal = FAILED;
  485.     
  486.     return RetVal;
  487. }
  488.